package com.baize.filedowndemo

import android.util.Log
import com.baize.filedowndemo.utils.FileUri
import com.liulishuo.okdownload.DownloadTask
import com.liulishuo.okdownload.StatusUtil
import com.liulishuo.okdownload.core.cause.EndCause
import com.liulishuo.okdownload.core.cause.ResumeFailedCause
import com.liulishuo.okdownload.core.listener.DownloadListener3
import com.liulishuo.okdownload.core.listener.assist.Listener1Assist
import java.lang.Exception

object OkDownloadManager {

  private val listeners = mutableListOf<OkDownloadListener>()

  private val listener3: DownloadListener3 by lazy {
    object : DownloadListener3() {
      override fun retry(task: DownloadTask, cause: ResumeFailedCause) {
        Log.i("baize_", "${task.filename} retry: ")
      }

      override fun connected(
        task: DownloadTask, blockCount: Int, currentOffset: Long, totalLength: Long
      ) {
        Log.i("baize_", "${task.filename} connected: ")
      }

      override fun progress(task: DownloadTask, currentOffset: Long, totalLength: Long) {
        val progress = (100f * currentOffset / totalLength).toInt()
        listeners.forEach { it.onProgress(task, progress) }
        Log.i(
          "baize_",
          "${task.filename} progress: $currentOffset $totalLength  $progress"
        ) //        if (task.filename == "test1.apk") {
        //          progressbar1.progress = progress
        //        }
        //        if (task.filename == "test2.apk") {
        //          progressbar2.progress = progress
        //        }
      }

      override fun started(task: DownloadTask) {
        Log.i("baize_", "${task.filename} started")
      }

      override fun completed(task: DownloadTask) {
        FileUri.writeFileToLocal(task.file!!)
        Log.i("baize_", "${task.filename} completed：${task.file?.exists()}")
      }

      override fun canceled(task: DownloadTask) {
        Log.i("baize_", "${task.filename} canceled")
      }

      override fun error(task: DownloadTask, e: Exception) {
        Log.i("baize_", "${task.filename} error:${e.message}")
      }

      override fun warn(task: DownloadTask) {
        Log.i("baize_", "${task.filename} warn:${task.file != null && task.file!!.exists()}")
        completed(task)
      }

      override fun taskEnd(
        task: DownloadTask,
        cause: EndCause,
        realCause: Exception?,
        model: Listener1Assist.Listener1Model
      ) {
        super.taskEnd(task, cause, realCause, model)
        Log.i("baize_", "${task.filename} taskEnd")
      }
    }
  }

  fun addObserve(listener: OkDownloadListener) {
    this.listeners.add(listener)
  }

  fun removeObserve(listener: OkDownloadListener) {
    this.listeners.remove(listener)
    Log.i("baize_", "listeners size : ${listeners.size}")
  }

  fun removeAllObserve() {
    this.listeners.clear()
  }

  /**
   * 开启一个下载任务
   */
  fun startDownloadTask(url: String, fileName: String) {
    val task = createDownloadTask(url to fileName)
    val status = StatusUtil.getStatus(task)
    Log.i("baize_","task " + fileName + " 状态：" + status.name)
    if (status != StatusUtil.Status.RUNNING) {
      task.enqueue(listener3)
    }
  }

  fun createDownloadTask(itemInfo: Pair<String, String>): DownloadTask {
    return DownloadTask
      .Builder(itemInfo.first, App.getApplication().cacheDir) //设置下载地址和下载目录，这两个是必须的参数
      .setFilename(itemInfo.second) //设置下载文件名，没提供的话先看 response header ，再看 url path(即启用下面那项配置)
      //      .setFilenameFromResponse(false) //是否使用 response header or url path 作为文件名，此时会忽略指定的文件名，默认false
      .setPassIfAlreadyCompleted(true) //如果文件已经下载完成，再次下载时，是否忽略下载，默认为true(忽略)，设为false会从头下载
      .setConnectionCount(1) //需要用几个线程来下载文件，默认根据文件大小确定；如果文件已经 split block，则设置后无效
      //      .setPreAllocateLength(false) //在获取资源长度后，设置是否需要为文件预分配长度，默认false
      .setMinIntervalMillisCallbackProcess(100) //通知调用者的频率，避免anr，默认3000
      .setWifiRequired(false) //是否只允许wifi下载，默认为false
      .setAutoCallbackToUIThread(true) //是否在主线程通知调用者，默认为true
      //.setHeaderMapFields(new HashMap<String, List<String>>())//设置请求头
      //.addHeader(String key, String value)//追加请求头
      .setPriority(0) //设置优先级，默认值是0，值越大下载优先级越高
      .setReadBufferSize(4096) //设置读取缓存区大小，默认4096
      .setFlushBufferSize(16384) //设置写入缓存区大小，默认16384
      .setSyncBufferSize(65536) //写入到文件的缓冲区大小，默认65536
      .setSyncBufferIntervalMillis(2000) //写入文件的最小时间间隔，默认2000
      .build()
  }

}

interface OkDownloadListener {
  fun onProgress(task: DownloadTask, progress: Int)
}

class Listener3Factory() {
  companion object {
    fun create(): DownloadListener3 {
      return object : DownloadListener3() {
        override fun retry(task: DownloadTask, cause: ResumeFailedCause) {
          Log.i("baize_", "${task.filename} retry: ")
        }

        override fun connected(
          task: DownloadTask, blockCount: Int, currentOffset: Long, totalLength: Long
        ) {
          Log.i("baize_", "${task.filename} connected: ")
        }

        override fun progress(task: DownloadTask, currentOffset: Long, totalLength: Long) {
          val progress = (100f * currentOffset / totalLength).toInt()
          Log.i(
            "baize_", "${task.filename} progress: $currentOffset $totalLength  $progress"
          ) //          if (task.filename == "test1.apk") {
          //            progressbar1.progress = progress
          //          }
          //          if (task.filename == "test2.apk") {
          //            progressbar2.progress = progress
          //          }
        }

        override fun started(task: DownloadTask) {
          Log.i("baize_", "${task.filename} started")
        }

        override fun completed(task: DownloadTask) {
          Log.i("baize_", "${task.filename} completed")
        }

        override fun canceled(task: DownloadTask) {
          Log.i("baize_", "${task.filename} canceled")
        }

        override fun error(task: DownloadTask, e: Exception) {
          Log.i("baize_", "${task.filename} error:${e.message}")
        }

        override fun warn(task: DownloadTask) {
          Log.i("baize_", "${task.filename} warn:${task.file != null && task.file!!.exists()}")
        }
      }
    }
  }
}